Skip to content

feat(state): let delta coroutines drop their key via sentinel#6673

Merged
masenf merged 6 commits into
reflex-dev:mainfrom
FarhanAliRaza:re-auth-state
Jun 24, 2026
Merged

feat(state): let delta coroutines drop their key via sentinel#6673
masenf merged 6 commits into
reflex-dev:mainfrom
FarhanAliRaza:re-auth-state

Conversation

@FarhanAliRaza

Copy link
Copy Markdown
Contributor

A coroutine value in a delta can now resolve to _DROP_FROM_DELTA to omit its key, so inclusion that can only be decided asynchronously is deferred into the delta and resolved post-hoc by _resolve_delta. Emptied state subdicts are removed as well.

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

A coroutine value in a delta can now resolve to _DROP_FROM_DELTA to omit
its key, so inclusion that can only be decided asynchronously is deferred
into the delta and resolved post-hoc by _resolve_delta. Emptied state
subdicts are removed as well.
@FarhanAliRaza FarhanAliRaza requested a review from a team as a code owner June 22, 2026 22:56
@codspeed-hq

codspeed-hq Bot commented Jun 22, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 3.27%

❌ 1 regressed benchmark
✅ 25 untouched benchmarks
⏩ 8 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_get_all_imports[_complicated_page] 2.8 ms 2.9 ms -3.27%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing FarhanAliRaza:re-auth-state (dccb4e5) with main (d6324cf)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces two related changes: a _DROP_FROM_DELTA sentinel that lets async coroutine values in a state delta signal their own omission (resolved post-hoc in _resolve_delta), and a fix to modify_state that rebinds EventContext.token to the token being modified so that shared-state fan-out tasks observe the correct client token rather than the actor's inherited context.

  • reflex/state.py: Adds _DROP_FROM_DELTA: Final = object() and updates _resolve_delta to delete any delta key whose coroutine resolves to the sentinel, pruning any state subdict left empty as a result. The two-pass approach (create all tasks first, then await sequentially) preserves existing parallelism and correctly handles mixed dropped/kept/plain-value subdicts.
  • reflex/app.py: modify_state now forks EventContext to the target token inside a contextlib.ExitStack, silently skipping the rebind when no EventContext is active (LookupError), and restores the original context on exit.
  • Tests: Four new async tests in test_state.py cover plain pass-through, partial drops, and full-subdict pruning; test_app.py adds a test verifying the token rebinding round-trip.

Confidence Score: 5/5

Safe to merge — both changes are well-scoped, the sentinel logic handles all mixed-value cases correctly, and the EventContext rebinding properly restores caller state on exit.

The _resolve_delta two-pass design keeps raw coroutine objects in the delta dict until explicitly deleted, so the if not delta[state_name] empty-check is always accurate even when multiple keys for the same state resolve to the sentinel. The ExitStack-based rebinding in modify_state uses try/except LookupError to no-op safely when no EventContext exists, and the callback correctly restores the original token. Test coverage addresses all relevant combinations.

No files require special attention.

Important Files Changed

Filename Overview
reflex/state.py Adds _DROP_FROM_DELTA sentinel and updates _resolve_delta to omit keys/subdicts whose coroutine resolves to it; logic is correct for all combinations of plain, kept, and dropped coroutine values.
reflex/app.py Rebinds EventContext inside modify_state to the target token using ExitStack; correctly handles the no-context (LookupError) case and restores the original context on exit.
tests/units/test_state.py Four new async tests cover plain-value pass-through, single-key drop, single-key emptying a subdict, and multiple-drops emptying a subdict; all edge cases are addressed.
tests/units/test_app.py New async test verifies that modify_state rebinds EventContext.token to the modified token and restores the caller's token on exit.
news/6673.bugfix.md Changelog entry covers only the modify_state token-rebinding fix; the _DROP_FROM_DELTA sentinel (the other half of this PR) is not mentioned — likely intentional since it is an internal API.

Reviews (4): Last reviewed commit: "chore(state): add Final to typing import..." | Re-trigger Greptile

Comment thread reflex/state.py Outdated
Comment thread tests/units/test_state.py
FarhanAliRaza and others added 5 commits June 23, 2026 06:01
Out-of-band modify_state (e.g. the shared-state fan-out recomputing
another client's delta) runs in a task that copied the triggering
event's EventContext. Fork and rebind the context to the modified
token so consumers inside -- delta resolution, computed vars -- observe
that token rather than the actor's inherited one. No-op when no
EventContext is set.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@masenf masenf merged commit 8945367 into reflex-dev:main Jun 24, 2026
105 of 106 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants